using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using Deepcode.Flux.Core.UI.Controls;
using Deepcode.Flux.Core.Systems.CMS;

namespace Deepcode.Flux.Core.UI.Controls
{
	/// <summary>
	/// Creates a collapsable section that asks for the standard embargo dates, including
	/// Checkbox indicating the item should only be published from a certain date, a date
	/// input indicating the start date for publishing, a checkbox indicating the item should
	/// expire along with a date input for the date it should expire, and also what expiry action
	/// should be taken, including: Nothing, Delete and Move to Node. A selector is also available
	/// for those with move to node selected that allows the selection of the parent page to move
	/// the content into.
	/// </summary>
	public class EmbargoSection : Deepcode.Flux.Core.UI.Controls.Base.BaseControl, INamingContainer
	{
		#region Properties
		/// <summary>
		/// Property stating whether the content has a publish from date
		/// </summary>
		public bool HasEmbargoStart
		{
			get
			{
				EnsureChildControls();
				return this._hasstart.Checked;
			}
			set
			{
				EnsureChildControls();
				this._hasstart.Checked = value;
				this._hasstart_CheckedChanged( this, EventArgs.Empty );
			}
		}
		/// <summary>
		/// Property stating the publish from date
		/// </summary>
		public DateTime PublishStartDT
		{
			get
			{
				EnsureChildControls();
				return this._publishFrom.DateTimeValue;
			}
			set
			{
				EnsureChildControls();
				this._publishFrom.Text = value.ToString("dd MMM yyyy HH:mm");
			}
		}
		/// <summary>
		/// Property stating whether the content has a publish until date
		/// </summary>
		public bool HasEmbargoEnd
		{
			get
			{
				EnsureChildControls();
				return this._hasexpiry.Checked;
			}
			set
			{
				EnsureChildControls();
				this._hasexpiry.Checked = value;
				this._hasexpiry_CheckedChanged( this, EventArgs.Empty );
			}
		}
		/// <summary>
		/// Property stating the publish until date
		/// </summary>
		public DateTime PublishUntilDT
		{
			get
			{
				EnsureChildControls();
				return this._publishUntil.DateTimeValue;
			}
			set
			{
				EnsureChildControls();
				this._publishUntil.Text = value.ToString("dd MMM yyyy HH:mm");
			}
		}
		/// <summary>
		/// Property stating the selected expiry action, if any
		/// </summary>
		public ContentExpiryMode ExpiryAction
		{
			get
			{
				EnsureChildControls();
				return this.GetSelectedExpiry();
			}
			set
			{
				EnsureChildControls();
				try
				{
					this._expiryAction.SelectedValue = ((int)value).ToString();
					this._expiryAction_SelectedIndexChanged( this, EventArgs.Empty );
				}
				catch
				{
				}
			}
		}
		/// <summary>
		/// Property stating the target node ID for a move action
		/// </summary>
		public int ExpiryActionDataID
		{
			get
			{
				EnsureChildControls();
				return this._expiryMoveLink.NodeID;
			}
			set
			{
				EnsureChildControls();
				this._expiryMoveLink.NodeID = value;
			}
		}
		#endregion
		#region Child Control Declarations
		protected CheckBox				_hasstart;
		protected DateInput				_publishFrom;
		protected DateInputValidator	_publishFromValidator;
		
		protected CheckBox				_hasexpiry;
		protected DateInput				_publishUntil;
		protected DateInputValidator	_publishUntilValidator;

		protected DropDownList			_expiryAction;
		protected ContentLink			_expiryMoveLink;
		protected ContentLinkValidator	_expiryMoveLinkValidator;
		#endregion
		#region Child control creation
		/// <summary>
		/// Creates the composite controls
		/// </summary>
		protected override void CreateChildControls()
		{
			base.CreateChildControls();

			// Create and add the section
			CollapseSection _section = new CollapseSection();
			_section.ID = "SECTION";
			_section.Title = "Publishing Properties";
			this.Controls.Add( _section );

			// Add the shade pad area
			ShadePadBox _shade = new ShadePadBox();
			_shade.ID = "SHADE";
			_section.Controls.Add( _shade );
			
			// Create and add the table
			Table t = new Table();
			t.ID = "TABLE";
			t.CellPadding = 3;
			t.CellSpacing = 0;
			t.BorderWidth = new Unit("0px");
			_shade.Controls.Add( t );

			// Add the row and cells for the checkbox
			TableRow r1 = new TableRow();
			r1.ID = "ROW1";
			t.Controls.Add( r1 );
			
			// Has publish - Caption cell
			TableCell r1c1 = new TableCell();
			r1c1.ID = "R1C1";
			r1c1.Wrap = false;
			r1c1.Text = "Has a publish start date:";
			r1.Controls.Add( r1c1 );
			
			// checkbox cell and checkbox
			TableCell r1c2 = new TableCell();
			r1c2.ID = "R1C2";
			r1.Controls.Add( r1c2 );
			_hasstart = new CheckBox();
			_hasstart.ID = "HASSTART";
			_hasstart.AutoPostBack = true;
			_hasstart.CheckedChanged += new EventHandler(_hasstart_CheckedChanged);
			r1c2.Controls.Add( _hasstart );

			// Dummy cell with spacer
			TableCell r1c3a = new TableCell();
			r1c3a.ID = "R1C3A";
			r1c3a.Visible = true;
			r1c3a.Text = "&nbsp;";
			r1.Controls.Add( r1c3a );

			// Cell with date input and validator
			TableCell r1c3b = new TableCell();
			r1c3b.ID = "R1C3B";
			r1c3b.Visible = false;
			r1.Controls.Add( r1c3b );

			_publishFrom = new DateInput();
			_publishFrom.ID = "PUBLISHFROM";
			_publishFrom.Type = DateInputType.WITHTIME;
			r1c3b.Controls.Add( _publishFrom );
	
			_publishFromValidator = new DateInputValidator();
			_publishFromValidator.ID = "PUBLISHFROMVALIDATOR";
			_publishFromValidator.ControlToValidate = "PUBLISHFROM";
			_publishFromValidator.Enabled = false;
			_publishFromValidator.Display = ValidatorDisplay.None;
			_publishFromValidator.ErrorMessage = "If using a publish from date, you must specify the date to publish from";
			r1c3b.Controls.Add( _publishFromValidator );

			// Add row with expiry selector
			TableRow r2 = new TableRow();
			r2.ID = "ROW2";
			t.Controls.Add( r2 );

			// Cell with caption
			TableCell r2c1 = new TableCell();
			r2c1.ID = "R2C1";
			r2c1.Wrap = false;
			r2c1.Text = "Expire Content:";
			r2.Controls.Add( r2c1 );

			// Cell with Checkbox
			TableCell r2c2 = new TableCell();
			r2c2.ID = "R2C2";
			r2.Controls.Add( r2c2 );

			_hasexpiry = new CheckBox();
			_hasexpiry.ID = "HASEXPIRY";
			_hasexpiry.AutoPostBack = true;
			_hasexpiry.CheckedChanged += new EventHandler(_hasexpiry_CheckedChanged);
			r2c2.Controls.Add( _hasexpiry );

			// Dummy cell with spacer
			TableCell r2c3a = new TableCell();
			r2c3a.ID = "R2C3A";
			r2c3a.Visible = true;
			r2c3a.Text = "&nbsp;";
			r2.Controls.Add( r2c3a );

			// Cell with date input and validator
			TableCell r2c3b = new TableCell();
			r2c3b.ID = "R2C3B";
			r2c3b.Visible = false;
			r2.Controls.Add( r2c3b );

			_publishUntil = new DateInput();
			_publishUntil.ID = "PUBLISHUNTIL";
			_publishUntil.Type = DateInputType.WITHTIME;
			r2c3b.Controls.Add( _publishUntil );
	
			_publishUntilValidator = new DateInputValidator();
			_publishUntilValidator.ID = "PUBLISHUNTILVALIDATOR";
			_publishUntilValidator.ControlToValidate = "PUBLISHUNTIL";
			_publishUntilValidator.Enabled = false;
			_publishUntilValidator.Display = ValidatorDisplay.None;
			_publishUntilValidator.ErrorMessage = "If expiring content, you must specify the date to expire it";
			r2c3b.Controls.Add( _publishUntilValidator );

			// Add row with options for selecting what to do with expiry
			TableRow r3 = new TableRow();
			r3.ID = "ROW3";
			r3.Visible = false;
			t.Controls.Add( r3 );

			// Caption cell
			TableCell r3c1 = new TableCell();
			r3c1.ID = "R3C1";
			r3c1.Text = "On Expiry:";
			r3.Controls.Add( r3c1 );

			// Cell with drop down list
			TableCell r3c2 = new TableCell();
			r3c2.ID = "R3C2";
			r3c2.ColumnSpan = 2;
			r3.Controls.Add( r3c2 );

			_expiryAction = new DropDownList();
			_expiryAction.Width = new Unit("300px");
			_expiryAction.ID = "EXPIRYACTION";
			_expiryAction.AutoPostBack = true;
			_expiryAction.SelectedIndexChanged += new EventHandler(_expiryAction_SelectedIndexChanged);

			_expiryAction.Items.Clear();
			_expiryAction.Items.Add( new ListItem("Do Nothing", "-1"));
			_expiryAction.Items.Add( new ListItem("Delete Content", "0"));
			_expiryAction.Items.Add( new ListItem("Move to child of node", "1"));

			r3c2.Controls.Add( _expiryAction );

			// Add row with options for selecting a page reference
			TableRow r4 = new TableRow();
			r4.ID = "ROW4";
			r4.Visible = false;
			t.Controls.Add( r4 );

			// Caption Cell
			TableCell r4c1 = new TableCell();
			r4c1.ID = "R4C1";
			r4c1.Text = "Move to child of node:";
			r4c1.Wrap = false;
			r4.Controls.Add( r4c1 );

			// Cell with page reference control and validator
			TableCell r4c2 = new TableCell();
			r4c2.ID = "R4C2";
			r4c2.ColumnSpan = 2;
			r4.Controls.Add( r4c2 );

			_expiryMoveLink = new ContentLink();
			_expiryMoveLink.ID = "EXPIRYMOVELINK";
			_expiryMoveLink.CanClear = false;
			_expiryMoveLink.Width = new Unit("300px");
			r4c2.Controls.Add( _expiryMoveLink );

			_expiryMoveLinkValidator = new ContentLinkValidator();
			_expiryMoveLinkValidator.ID = "EXPIRYMOVELINKVALIDATOR";
			_expiryMoveLinkValidator.Enabled = false;
			_expiryMoveLinkValidator.ControlToValidate = "EXPIRYMOVELINK";
			_expiryMoveLinkValidator.Display = ValidatorDisplay.None;
			_expiryMoveLinkValidator.ErrorMessage = "To move the content on expiry you must select which node to move the content to";
			r4c2.Controls.Add( _expiryMoveLinkValidator );
		}
		#endregion
		#region Interactions
		/// <summary>
		/// User has changed the "has start date" checkbox value
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		void _hasstart_CheckedChanged(object sender, EventArgs e)
		{
			EnsureChildControls();
			// Get the two cells
			TableCell r1c3a = (TableCell) this.FindControl("R1C3A");
			TableCell r1c3b = (TableCell) this.FindControl("R1C3B");
			if( r1c3a == null || r1c3b == null ) return;

			if (_hasstart.Checked)
			{
				r1c3a.Visible = false;
				r1c3b.Visible = true;
				_publishFromValidator.Enabled = true;
			}
			else
			{
				r1c3a.Visible = true;
				r1c3b.Visible = false;
				_publishFromValidator.Enabled = false;
			}
		}
		/// <summary>
		/// User has changed the "has expiry date" checkbox value
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		void _hasexpiry_CheckedChanged(object sender, EventArgs e)
		{
			EnsureChildControls();
			// Get the two cells
			TableCell r2c3a = (TableCell) this.FindControl("R2C3A");
			TableCell r2c3b = (TableCell) this.FindControl("R2C3B");
			TableRow row3 = (TableRow) this.FindControl("ROW3");
			TableRow row4 = (TableRow) this.FindControl("ROW4");

			if( r2c3a == null || r2c3b == null || row3 == null ) return;

			if (_hasexpiry.Checked)
			{
				r2c3a.Visible = false;
				r2c3b.Visible = true;
				_publishUntilValidator.Enabled = true;
				row3.Visible = true;
				row4.Visible = false;
				if( GetSelectedExpiry() == ContentExpiryMode.MOVETONODE ) row4.Visible = true;
			}
			else
			{
				r2c3a.Visible = true;
				r2c3b.Visible = false;
				_publishUntilValidator.Enabled = false;
				row3.Visible = false;
				row4.Visible = false;
			}
		}
		/// <summary>
		/// User has specified what action to take on expiry
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		void _expiryAction_SelectedIndexChanged(object sender, EventArgs e)
		{
			// Get the row
			TableRow r4 = (TableRow) FindControl("ROW4");
			if( r4 == null ) return;

			// Get the value from the drop down list
			ContentExpiryMode cem = GetSelectedExpiry();

			// Adjust form based on value
			if (cem == ContentExpiryMode.MOVETONODE)
			{
				r4.Visible = true;
				_expiryMoveLinkValidator.Enabled = true;
			}
			else
			{
				r4.Visible = false;
				_expiryMoveLinkValidator.Enabled = false;
			}
		}
		/// <summary>
		/// Gets the selected expiry mode
		/// </summary>
		/// <returns></returns>
		protected ContentExpiryMode GetSelectedExpiry()
		{
			ContentExpiryMode cem = ContentExpiryMode.NOTHING;
			if( ! _hasexpiry.Checked ) return cem;
			try
			{
				int iValue = Int32.Parse( _expiryAction.SelectedValue );
				cem = (ContentExpiryMode) iValue; 
			}
			catch
			{ 
				cem = ContentExpiryMode.NOTHING; 
			}
			return cem;
		}
		#endregion
		#region Quick save / load operations to and from ContentObjects
		/// <summary>
		/// Sets the various embargo date values in the content object 
		/// to those from this instance of the control
		/// </summary>
		/// <param name="save"></param>
		public void QuickSave(ref ContentObject save)
		{
			save.HasEmbargoStart = this.HasEmbargoStart;
			save.PublishStartDT = this.PublishStartDT;
			save.HasEmbargoEnd = this.HasEmbargoEnd;
			save.PublishUntilDT = this.PublishUntilDT;
			save.ExpiryActionID = this.ExpiryAction;
			save.ExpiryActionDataID = this.ExpiryActionDataID;
		}
		/// <summary>
		/// Loads the various dates etc from the content object onto
		/// this instance of the control
		/// </summary>
		/// <param name="load"></param>
		public void QuickLoad(ContentObject load)
		{
			this.HasEmbargoStart = load.HasEmbargoStart;
			this.PublishStartDT = load.PublishStartDT;
			this.HasEmbargoEnd = load.HasEmbargoEnd;
			this.PublishUntilDT = load.PublishUntilDT;
			this.ExpiryAction = load.ExpiryActionID;
			this.ExpiryActionDataID = load.ExpiryActionDataID;
		}
		#endregion
	}
}
